package com.hospital.register.order.service.impl;

import com.hospital.register.common.exception.BusinessException;
import com.hospital.register.common.result.ResultCodeEnum;
import com.hospital.register.dto.order.PaymentListDto;
import com.hospital.register.enums.RefundStatusEnum;
import com.hospital.register.model.order.RefundInfo;
import com.hospital.register.order.mapper.RefundInfoMapper;
import com.hospital.register.order.service.PaymentInfoService;
import com.hospital.register.order.service.RefundInfoService;
import com.hospital.register.vo.order.PaymentListVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.List;

@Service
public class RefundInfoServiceImpl implements RefundInfoService {

    /**
     * 访问退款信息
     */
    @Autowired
    private RefundInfoMapper refundInfoMapper;

    /**
     * 处理支付业务
     */
    @Autowired
    private PaymentInfoService paymentInfoService;

    @Override
    public boolean insert(RefundInfo refundInfo) {
        return this.refundInfoMapper.insert(refundInfo) == 1;
    }

    @Override
    public RefundInfo generateIfAbsent(Long orderId, Byte paymentType) {
        // 如果该订单已有对应类型的退款记录，则不生成
        RefundInfo oldRefundInfo = this.selectByConditions(orderId, paymentType, null);

        if (oldRefundInfo != null) {
            return oldRefundInfo;
        }

        // 查询该订单对应的支付记录
        PaymentListDto paymentConditions = new PaymentListDto();
        paymentConditions.setOrderId(orderId);
        paymentConditions.setPaymentType(paymentType);
        paymentConditions.setFilterFail(true);
        paymentConditions.setUnique(true);

        List<PaymentListVo> paymentList = paymentInfoService.list(paymentConditions);
        if (paymentList == null || paymentList.size() == 0) {
            throw new BusinessException("订单退款失败，未能查询到对应的支付记录", ResultCodeEnum.CANCEL_ORDER_FAIL.getCode());
        }

        PaymentListVo payment = paymentList.get(0);
        Date currentTime = new Date();

        RefundInfo refund = new RefundInfo();
        refund.setCreateTime(currentTime);
        refund.setUpdateTime(currentTime);
        refund.setOrderId(orderId);
        refund.setPaymentType(payment.getPaymentType());
        refund.setOutTradeNo(payment.getOutTradeNo());
        refund.setRefundStatus(RefundStatusEnum.UNREFUND.getStatus());
        refund.setSubject(payment.getSubject());
        refund.setTotalAmount(payment.getTotalAmount());
        refund.setTradeNo(payment.getTradeNo());//退款完成后会修改为退款本身的交易号
        this.insert(refund);
        return refund;
    }

    @Override
    public RefundInfo selectByConditions(Long orderId, Byte paymentType, Byte refundStatus) {
        return this.refundInfoMapper.selectByConditions(orderId, paymentType,
                refundStatus);
    }

    @Override
    public boolean deleteById(Long id, Date deletionTime) {
        return this.refundInfoMapper.deleteById(id, deletionTime) == 1;
    }

    @Override
    public boolean updateById(RefundInfo refundInfo) {
        if (refundInfo.getOrderId() != null) {
            throw new BusinessException("订单退款失败，不能修改订单编号", ResultCodeEnum.CANCEL_ORDER_FAIL.getCode());
        }

        return refundInfo.willUpdateById() &&
                this.refundInfoMapper.updateById(refundInfo) == 1;
    }

}
